home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Shareware / Comunicatii / jaeger / jaeger.exe / {app} / Tools / Tool.py next >
Text File  |  2004-05-01  |  7KB  |  273 lines

  1. #!/bin/python
  2. # -*- coding: iso-8859-1 -*-
  3.  
  4. """
  5. Tool.py
  6.  
  7. David Janes
  8. BlogMatrix
  9. 2004.02.12
  10. """
  11.  
  12. import os.path
  13. import cgi
  14. import xml.sax.saxutils
  15.  
  16. #
  17. #    Forced inclusions for py2exe
  18. #
  19. import Cheetah.Template
  20. import poplib
  21. import email
  22. import email.Utils
  23.  
  24. class ToolSelected:
  25.     """
  26.     Represents a selected weblog, entry or source
  27.     """
  28.     def __init__(self):
  29.         self.identity = None
  30.  
  31.         self.url = None                    # use this for Tool actions, unless you know better
  32.  
  33.         self.weblog_url = None
  34.         self.entry_url = None
  35.         self.browser_url = None
  36.  
  37.         self.syndication_url = None
  38.  
  39.         self.weblog_title = None
  40.         self.entry_title = None
  41.  
  42. class ToolOperations:
  43.     """
  44.     Things you can do to Jaeger. Must be called within 'ToolInterface.invoke_for_*'
  45.     """
  46.     def __init__(self):
  47.         pass
  48.  
  49.     def open_url(self, url, force_new_window = False):
  50.         """
  51.         Open this url in the user's browser
  52.         """
  53.         pass
  54.  
  55.     def subscribe_to(self, url):
  56.         """
  57.         Start the Subscribe to Weblog wizard with this url
  58.         """
  59.  
  60.     def get_userdata(self, key, otherwise):
  61.         """
  62.         Retrieve some user data
  63.         """
  64.         return    otherwise
  65.  
  66.     def set_userdata(self, key, value):
  67.         """
  68.         Sets some user data
  69.         """
  70.         pass
  71.  
  72.     def get_weblogs(self):
  73.         """
  74.         Return a list of dictionaries, each dictionary being a weblog.
  75.         There is no particular order to the data.
  76.         """
  77.  
  78.     def log(self, message):
  79.         """
  80.         Log the message to the console
  81.         """
  82.  
  83. tools = []
  84.  
  85. class ToolInterface:
  86.     """
  87.     The interface for your tool. Simply create an instance of this object and Jaeger
  88.     will figure it out.
  89.     """
  90.     ON_WEBLOG        = 0x01        # weblog only selected
  91.     ON_ENTRY        = 0x02        # entry only selected
  92.     ON_SOURCE        = 0x04        # item in source pane selected
  93.     IF_BROWSER        = 0x08        # IF something is displayed in browser AND 'Use Browser URL' selected
  94.     ON_NOTHING        = 0x10        # nothing is selected
  95.     ON_SOMETHING    = ON_WEBLOG|ON_ENTRY|ON_SOURCE|IF_BROWSER
  96.     ON_ALL            = ON_SOMETHING|ON_NOTHING
  97.  
  98.     WEBSERVER        = 0x20        # serves web pages
  99.  
  100.     def __init__(self, capabilities = ON_SOMETHING):
  101.         self.capabilities = capabilities
  102.  
  103.         self.name = str(self.__class__)
  104.         dotx = self.name.rfind('.')
  105.         if dotx > -1: self.name = self.name[dotx + 1:]
  106.         if self.name[:4] == "Tool": self.name = self.name[4:]
  107.  
  108.         tools.append(self)
  109.  
  110.     def get_group(self):
  111.         """
  112.         The name for a tool submenu. Tools with the same
  113.         group name are placed under the same submenu.
  114.         """
  115.         return    None
  116.  
  117.     def get_label(self, selected):
  118.         """
  119.         You _must_ define this function in your subclass. It defines the greyed
  120.         out menu item text.
  121.  
  122.         'selected' _may_ be None during the initialization phase
  123.         """
  124.         raise "ToolInterface.get_label not defined"
  125.  
  126.     def invoke(self, selected, operations):
  127.         """
  128.         This is called to 'do the action' of the tool. This is probably
  129.         where the bulk of your code will go if you're writing something
  130.         reactive to user's code
  131.         """
  132.         return
  133.  
  134.     def pulse(self, operations):
  135.         """
  136.         This function is called periodically, about once a minute. Each
  137.         extension is called sequentially and should avoid hogging the thread
  138.         """
  139.  
  140.     def get_server(self, path):
  141.         """
  142.         For the given 'path', return ( method, page name ), or None
  143.         if the page is not to be served.
  144.  
  145.         'method' will serve the contents and takes the arguments:
  146.             ( self, operations, path, valuemap)
  147.         and will return
  148.             ( status, content_type, header_map, body_text )
  149.             - status is typically 200 or 404
  150.             - 'body_text' may be a string, or list of strings.
  151.         """
  152.         return    None
  153.  
  154.     def serve_webpage(self, operations, path, valuemap):
  155.         result = self.get_server(path)
  156.         if not result:
  157.             return    self.serve_filenotfound()
  158.  
  159.         return    result[0](operations, path, valuemap)
  160.  
  161.     #
  162.     #    --- helper stuff below here ---
  163.     #
  164.     def tool_root(self, full = False):
  165.         port = 5335
  166.         try:
  167.             import BlogHTTPD
  168.             port = BlogHTTPD.standard_port
  169.         except:
  170.             print >> sys.stderr, "Tool.tool_root: problem importing BlogHTTPD?"
  171.  
  172.         # print >> sys.stderr, "Tool.PORT", port
  173.  
  174.         if full:
  175.             return    "http://127.0.0.1:%d/tools/%s/" % ( port, self.name )
  176.         else:
  177.             return    "/tools/%s/" % self.name
  178.  
  179.     def escape_html(self, text):
  180.         """
  181.         Quote for inclusion in HTML text (i.e. deal with <, >, & and ")
  182.         """
  183.         return    cgi.escape(text, True)
  184.  
  185.     def quote_attribute(self, text):
  186.         """
  187.         Quote for inclusion in XML attribute
  188.         (i.e. add surrounding quotes, deal with <, >, & and " and ')
  189.         """
  190.         return    xml.sax.saxutils.quoteattr(text)
  191.  
  192.     def text_standard_header(self, path):
  193.         breadcrumbs = '<span style="color: FF2A00">%s</span>' % self.escape_html(self.name)
  194.  
  195.         #
  196.         #    build up the path description
  197.         #
  198.         pathlist = []
  199.  
  200.         while path != "/":
  201.             result = self.get_server(path)
  202.             if result:
  203.                 pathlist.append(( path, result[1] ))
  204.  
  205.             path, base = os.path.split(path)
  206.  
  207.         result = self.get_server("/")
  208.         if not result or not result[1]: pathlist.append(( "/", self.name + " Extension" ))
  209.         else: pathlist.append(( "/", self.name + " Extension: " + result[1] ))
  210.  
  211.         pathlist.reverse()
  212.  
  213.         breadcrumbs = []
  214.         for path, name in pathlist[:-1]:
  215.             breadcrumbs.append('<a href="%s">%s</a>' %
  216.                 ( self.escape_html(self.tool_root() + path[1:]), self.escape_html(name) ))
  217.         breadcrumbs.append('<span style="color: FF2A00">%s</span>' % ( self.escape_html(pathlist[-1][1]) ))
  218.         breadcrumbs = " > ".join(breadcrumbs)
  219.  
  220.         #
  221.         #    return the result
  222.         #
  223.         return    """\
  224. <html>
  225. <head>
  226. <title>BlogMatrix JΣger</title>
  227. <link type="text/css" rel="stylesheet" href="/css/style.css">
  228. <basefont face="Georgia" size=2>
  229. </head>
  230. <body bgcolor="#FFFFFF" link="#225588" alink="#993333" vlink="#225588">
  231. <div class="content" sty>
  232. <h1>BlogMatrix <span style="color: FF2A00">JΣger</span></h1>
  233. <div class="breadcrumb2">
  234. """ + breadcrumbs + """
  235. </div>
  236. <div class="rule"></div>
  237. """
  238.  
  239.     def text_standard_footer(self):
  240.         return    """<br clear=all><div class="rule"></div></body></html>"""
  241.  
  242.  
  243.     def text_filenotfound(self):
  244.         return    """\
  245. <html>
  246. <head>
  247. <title>BlogMatrix JΣger</title>
  248. <link type="text/css" rel="stylesheet" href="/css/style.css">
  249. <basefont face="Georgia" size=2>
  250. </head>
  251. <body bgcolor="#FFFFFF" link="#225588" alink="#993333" vlink="#225588">
  252. <div class="content" sty>
  253. <h1>BlogMatrix <span style="color: FF2A00">JΣger</span></h1>
  254. <div class="breadcrumb2">
  255. <span style="color: FF2A00">""" + self.escape_html(self.name) + """ Extension</span>
  256. </div>
  257. <p>
  258. File not found
  259. <!--
  260. -=----------------------------------------------
  261. -=----------------------------------------------
  262. -=----------------------------------------------
  263. -=----------------------------------------------
  264. -=----------------------------------------------
  265. -=----------------------------------------------
  266. -->
  267. </body>
  268. </html>
  269. """
  270.  
  271.     def serve_filenotfound(self):
  272.         return    ( 404, "text/html", None, self.text_filenotfound() )
  273.